<template>
    <div ref="refNode" :class="$style['card-wrapper']">
        <div :class="$style['title']">
            <CyIcon :class="$style['icon']" :code="info.icon" v-if="info.icon" />
            <h6>联动动作</h6>

            <!-- 在 x6 的 vue 组件节点上，再抽象出一个组件，在渲染时出现了明显的卡顿情况，暂时就先不做操作组件的分离了 -->
            <el-dropdown placement="right-start" @visible-change="handleChangeCommandVisible" @command="handleCommand">
                <el-icon :class="$style['operation']" color="#FFF" :size="16">
                    <Operation />
                </el-icon>

                <template #dropdown>
                    <el-dropdown-menu>
                        <template :key="item.command" v-for="item in operationOptions">
                            <el-dropdown-item :command="item.command">{{ item.label }}</el-dropdown-item>
                        </template>
                    </el-dropdown-menu>
                </template>
            </el-dropdown>
        </div>

        <div :class="$style['content']">{{ info.name }}</div>
    </div>
</template>

<script setup>
/**
 * 这里触发的事件，统一从 @/../workflow.event.js 的 useInject 函数中中引入
 * 事件会通过 emitEvent.emit 到 [工作流的业务页面] 触发 operationOptions 定义的具体操作事件
 */
import { computed, inject, nextTick, onMounted, ref } from 'vue'
import { Operation } from '@element-plus/icons-vue'
import { useInject } from '@/utils/workflow/workflow.event'

import CyIcon from '@/components/Icon.vue'

import { enumEventModule, enumEventName } from '@/utils/emunEvent'

const { getWorkflowCls, emitEvent } = useInject()

const moduleTitleMap = {
    event: '审批节点',
    judgment: '审批节点',
    judgmentValid: '审批通过',
    judgmentInvalid: '审批未通过'
}

const refNode = ref()

const info = ref({
    icon: '',
    content: '内容'
})

// const isJudgment = computed(() => {
//     return info.value.module === enumEventModule.judgment
// })

const hadEventLine = ref(false)
const hadValidLine = ref(false)
const hadInvalidLine = ref(false)
const hadNextLine = ref(false)

const operationOptions = computed(() => {
    const options = [
        { command: enumEventName.appendEvent, label: '添加节点' },
        { command: enumEventName.modifyEvent, label: '编辑节点' },
        { command: enumEventName.removeNode, label: '删除节点' }
    ]

    if (!hadEventLine.value) {
        if (hadValidLine.value || hadInvalidLine.value) {
            if (hadValidLine.value && !hadInvalidLine.value) {
                options.unshift({ command: enumEventName.appendInvalidEvent, label: '添加未通过节点' })
            }

            if (hadInvalidLine.value && !hadValidLine.value) {
                options.unshift({ command: enumEventName.appendValidEvent, label: '添加通过节点' })
            }
        } else {
            // options.unshift(
            //     { command: enumEventName.appendEvent, label: '添加节点' },
            //     // {command: enumEventName.appendValidEvent, label: '添加通过节点'},
            //     // {command: enumEventName.appendInvalidEvent, label: '添加未通过节点'}
            // )
        }
    }

    if (!hadNextLine.value) {
        options.push({ command: enumEventName.nodeToEnd, label: '标记结束' })
    }

    return options
})

// x6 vue 组件自带的 provide，用于获取由 x6 创建的 node 数据
const getNode = inject('getNode')
const node = getNode()

// 重置当前 node 的尺寸，用于布局使用
const setSize = async () => {
    await nextTick()
    node.setSize(refNode.value.clientWidth, refNode.value.clientHeight)
}

const handleCommand = (cmd) => {
    // console.log('🚀 ~ handleCommand ~ cmd:', cmd)
    getWorkflowCls((cls) => {
        emitEvent('event:touch', {
            type: cmd,
            data: cls.getExtraNode(node.id)
        })
    })
}

/**
 * 操作菜单在显示时，根据下级节点来控制具体的操作事项
 * @param visible 
 */
const handleChangeCommandVisible = (visible) => {
    if (!visible) {
        return
    }

    // 这里需要强制重置一下状态，否则在不触发操作的情况下，画板其他节点的操作这里不会更新
    hadEventLine.value = undefined
    hadValidLine.value = undefined
    hadInvalidLine.value = undefined
    hadNextLine.value = undefined
    getWorkflowCls((cls) => {
        const extraData = cls.getExtraNode(node.id)
        hadNextLine.value = !!extraData.to?.length
        extraData.to?.forEach(id => {
            const toNode = cls.getExtraNode(id)
            switch (toNode.data?.module) {
                case enumEventModule.judgmentValid:
                    hadValidLine.value = true
                    break
                case enumEventModule.judgmentInvalid:
                    hadInvalidLine.value = true
                    break
                default:
                    hadEventLine.value = true
                    break
            }
        })

        console.log('🚀 ~ getWorkflowCls ~ hadNextLine.value:', hadEventLine.value)
    })
}

node.on('change:data', ({ current }) => {
    // console.log('🚀 ~ node.on ~ current:', current)
    info.value = { id: node.id, ...current }
    setSize()
})

node.on('change:warning', ({ current }) => {
    // console.log('🚀 ~ node.on ~ change:warning:', current)
})

onMounted(() => {
    info.value = { id: node.id, ...node.getData() }
    setSize()
    getWorkflowCls(cls => cls.layout())
    // console.log('🚀 onMounted',node.getData())
})
</script>

<style lang="scss" module>
.card-wrapper {
    position: relative;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 200px;
    min-height: 80px;
    border-radius: 5px;
    box-shadow: 5px 5px 10px 2px #0003;
    white-space: normal;
    word-break: break-word;
    transition-property: box-shadow;
    transition-duration: 0.3s;

    &:hover {
        box-shadow: 5px 5px 12px 5px #0003;
    }
}

.title {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    width: 100%;
    height: 28px;
    padding: 5px 10px;
    background-color: #1E83E9;
    border-radius: 5px 5px 0 0;
    color: #FFF;

    h6 {
        flex: 1;
        width: 0;
        margin: 0 8px;
        @include lineFont(14, 500);
        @extend %row;
    }
}

.icon {
    width: 16px;
    height: 16px;
    @include lineFont(16);
    color: inherit;
}

.content {
    box-sizing: border-box;
    width: 100%;
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 10px;
    background-color: #FFF;
    border-radius: 0 0 5px 5px;
    word-break: break-all;
    line-height: 20px;
    @include font(14);
    color: #5A5E66;
}
</style>